﻿using Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using LoginModel.Entity;
using Server.Entity;
using Server.Utils;
using SocketServerHelper = Server.Utils.SocketServerHelper;
using Timer = System.Windows.Forms.Timer;

namespace Server
{
    public partial class FrmServer : Form
    {
        //是否结束运行
        private bool _isStopping = false;

        /// <summary>
        /// 判断窗体是否正常关闭
        /// </summary>
        private bool _isCloseWindows = false;

        private SocketServerHelper socketServerHelper;

        private CancellationTokenSource cancellation;   //取消Task动作
        private bool _isCancel = false;
        private Task task;
        private bool _isFirst = false;

        //private GlobalConstants global;

        public FrmServer()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 登录用户信息
        /// </summary>
        public User User { get; set; }

        private void Form1_Load(object sender, EventArgs e)
        {
            #region 加载登录窗体Dll
            //lvLog.Items.Add(new ListViewItem(new string[] { DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss"), "10.241.51.144:65535", "333333", "4444" }));
            //var loginFrm = new LoginModel.LoginModel("-服务端");
            //if (loginFrm.ShowDialog() == DialogResult.OK)
            //{
            //   User = loginFrm.User;
            //   listBox1.Items.Add(User.F004);
            //}
            //else
            //{
            //    Environment.Exit(0);
            //}
            #endregion



            if (GlobalConstants.ReadIniParam() == false)
            {
                MessageBox.Show(@"加载初始配置失败！请检查App.config文件是否正确配置", @"提示");
                return;
            }
            this.RefListViewSysInfoMessage("基本配置和端口号加载成功");
            _isCloseWindows = true;

           
          //  LbPartNo.Text = @"Test";
        }

        private void BtnStart_Click(object sender, EventArgs e)
        {

        }

        #region [窗体关闭事件]
        private void FrmServer_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_isCloseWindows)
            {
                DialogResult result =
                    MessageBox.Show(@"确认退出?", @"提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                {
                    _isStopping = true;
                    if (this.listView_Position.Items.Count > 0)
                    {
                        this.listView_Position.Invoke(new MethodInvoker(() =>
                        {
                            foreach (ListViewItem items in this.listView_Position.Items)
                            {
                                this.DisConnectionCallBack(items.SubItems[0].Text);
                            }
                        }));
                    }
                    e.Cancel = false;
                }
                else
                    e.Cancel = true;
            }
        }
        #endregion 


        #region [监听客户端]
        /// <summary>
        /// 开始监听客户端
        /// </summary>
        /// <returns></returns>
        private bool StartListen()
        {
            try
            {
                socketServerHelper = new SocketServerHelper(GlobalConstants.LocalPort)
                {
                    ReciveAction = ReciveCallBack,
                    LogAction = LogCallBack,
                    SendProgressAction = SendProgreeCallBack,
                    DisconnectAction = DisConnectionCallBack
                };
                socketServerHelper.Start();
                _isFirst = true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, @"错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                LogHelper.Error(e);
                _isFirst = false;
                return false;
            }
            return socketServerHelper.IsConnected;
        }

        private void DisConnectionCallBack(string ip)
        {
            var p = socketServerHelper.PositionList.Find(i => i.PositionIp == ip);
            RefreshForm(p, PositionType.PositionOffline);
            socketServerHelper.PositionList.Remove(p);
        }

        private void SendProgreeCallBack(string ip,string fileName, int size, long length, bool isLastFile)
        {
            if (socketServerHelper.PositionList.Count > 0)
            {
                foreach (var p in socketServerHelper.PositionList)
                {
                    if (p.PositionIp == ip)
                    {
                        p.PositionUpProcess = Convert.ToInt32(Math.Ceiling((1.0 * size / length) * 100)).ToString();
                        if (p.PositionUpProcess == "0")
                        {
                            RefreshForm(p, PositionType.FileStart);
                        }
                        else if (p.PositionUpProcess != "100")
                        {
                            RefreshForm(p, PositionType.FileUploadProcess);
                        }
                    }
                }
            }

        }

        private void LogCallBack(string ip, string msg)
        {
            if (socketServerHelper.IsConnected == false)
                RefListViewSysInfoMessage(ip);


            if (socketServerHelper.ClientMsgModelInfo?.PositionInfo != null && socketServerHelper.PositionList.Count > 0)
            {
                foreach (var p in socketServerHelper.PositionList)
                {
                    if (p.PositionIp == ip)
                    {
                        p.TestState = msg;

                        if (msg.Contains("发送完成"))
                        {
                            string[] fileName = msg.Split(';');
                            var positionDetail = new PositionDetail
                            {
                                DateTimeStr = StringUtils.GetDateStr(),
                                FileName = fileName[1]
                            };

                            p.PositionDetailsList.Add(positionDetail);
                            
                          
                        }
                    }
                }
            }

           
        }

        private void ReciveCallBack(SendType sendType, string msg)
        {
            this.Invoke(new Action(() =>
            {

                if (sendType == SendType.对象)
                {
                    socketServerHelper.ClientMsgModelInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientMsgModel>(msg);
                    if (socketServerHelper.ClientMsgModelInfo?.PositionInfo == null) return;

                    if (string.IsNullOrEmpty(socketServerHelper.ClientMsgModelInfo.Status)) return;
                    if (string.IsNullOrEmpty(LbPartNo.Text)) return;

                   
                    socketServerHelper.ClientMsgModelInfo.PositionInfo.PartNo = LbPartNo.Text;
                    socketServerHelper.ClientMsgModelInfo.PositionInfo.PositionIp = socketServerHelper.ClientMsgModelInfo.IP;
                    socketServerHelper.ClientMsgModelInfo.PositionInfo.PositionName =
                        socketServerHelper.ClientMsgModelInfo.Status;
                    socketServerHelper.ClientMsgModelInfo.PositionInfo.TestState = "连接成功";

                    socketServerHelper.PositionList.Add(socketServerHelper.ClientMsgModelInfo.PositionInfo);
                    foreach (var p in socketServerHelper.PositionList)
                    {
                        RefreshForm(p, PositionType.PositionOnline);
                    }
                   
                }
            }));
        }

        #endregion


        private bool GetLocalFolder(string folderName, string ip)
        {
            var p = socketServerHelper.PositionList.Find(i => i.PositionIp == ip);
            if (!Directory.Exists(folderName))
            {
                p.TestState = $@"未发现此文件夹,请先建立{folderName}文件夹";
                LogHelper.Info($"未查询到{folderName}文件夹");
                return false;
            }
            var files = Directory.GetFiles(folderName);
            if (files.Length == 0)
            {
                p.TestState = $"未发现此文件夹下包含文件";
                return false;
            }
            return true;
        }

        #region "日志处理操作"
        /// <summary>
        /// 日志处理
        /// </summary>
        /// <param name="ipPort"></param>
        /// <param name="msg"></param>
        //private void log(string ipPort, string msg, string position)
        //{
        //    if (lvLog.InvokeRequired)
        //    {
        //        lvLog.Invoke(new Action<ListViewItem>((item) => lvLog.Items.Add(item)),
        //            new ListViewItem(
        //                            new string[] { DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss"),
        //                                position.Trim(),
        //                            ipPort.Trim(),
        //                            msg.Trim()

        //            }
        //        ));
        //    }
        //    else
        //    {
        //        lvLog.Items.Add(new ListViewItem(
        //            new string[] { DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss"),
        //                            position.Trim(),
        //                            ipPort.Trim(),
        //                            msg.Trim()

        //            }
        //        ));
        //    }


        //}

        /// <summary>
        /// 日志处理
        /// </summary>
        /// <param name="ipPort"></param>
        /// <param name="msg"></param>
        /// <param name="size"></param>
        //private void log(string ipPort, byte[] msg,int size)
        //{
        //    if (lvLog.InvokeRequired)
        //    {
        //        lvLog.Invoke(new Action<ListViewItem>((item) => lvLog.Items.Add(item)),
        //            new ListViewItem(
        //                            new string[] { DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss"), 
        //                            ipPort.Trim(),
        //                            Encoding.UTF8.GetString(msg,1,size).Trim()
        //            }
        //        ));
        //    }
        //    else
        //    {
        //        lvLog.Items.Add(new ListViewItem(
        //            new string[] { DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss"), 
        //                            ipPort.Trim(),
        //                            Encoding.UTF8.GetString(msg,0,size).Trim()
        //            }
        //        ));
        //    }
        //}
        #endregion

        #region [刷新ListView_Position控件]
        private void RefreshForm(Position position, PositionType positionType)
        {
            if (_isStopping) return;

            try
            {
                this.listView_Position.Invoke(new Action<Position, PositionType>((x, y) =>
                {
                        #region MyRegion

                        //ListViewItem item;
                        //int index = this.listView_Position.Items.IndexOfKey(p.PositionIp);
                        //if (index != -1)
                        //    item = this.listView_Position.Items[index];
                        //else
                        //{
                        //    //站位IP地址
                        //    item = listView_Position.Items.Add("");
                        //    //站位名称
                        //    item.SubItems.Add("");
                        //    //文件存放路径
                        //    item.SubItems.Add("");
                        //    //站位状态
                        //    item.SubItems.Add("");
                        //    //上传状态
                        //    item.SubItems.Add("");
                        //    //站位ID
                        //    item.SubItems.Add("");
                        //    //Key
                        //    item.Name = p.PositionIp;
                        //}

                        //switch (y)
                        //{
                        //    #region [站位上线]

                        //    case PositionType.PositionOnline:
                        //        {
                        //            //本地文件夹路径
                        //            socketServerHelper.ClientMsgModelInfo.PositionInfo.PositionFolder =
                        //                $@"{GlobalConstants.Disk}{p.PositionName}\{p.PartNo}";
                        //            item.SubItems[0].Text = p.PositionIp;
                        //            item.SubItems[1].Text = p.PositionName;
                        //            item.SubItems[2].Text = p.PositionFolder;
                        //            item.SubItems[3].Text = p.TestState;
                        //            item.SubItems[4].Text = @"0";
                        //            break;
                        //        }

                        //    #endregion

                        //    #region [站位下线]

                        //    case PositionType.PositionOffline:
                        //        {
                        //            //.SubItems[3].Text = $@"{conn.PositionInfo.PositionName}下线";
                        //            this.listView_Position.Items.RemoveByKey(p.PositionIp);
                        //            this.RefListViewSysInfoMessage(
                        //                $"IP地址：{p.PositionIp} 站位名：{p.PositionName}下线");
                        //            break;
                        //        }


                        //    #endregion

                        //    #region [站位开始上传]

                        //    case PositionType.FileStart:
                        //        {

                        //            item.SubItems[3].Text = p.TestState;
                        //            item.SubItems[4].Text = p.PositionUpProcess;
                        //            // btnSendFile.Enabled = false;
                        //            //timer1.Enabled = true;
                        //            //timer1.Start();
                        //            // Thread.Sleep(1000);
                        //            //  MessageBox.Show("ok");
                        //            // this.RefPositionDetail();
                        //            break;
                        //        }

                        //    #endregion

                        //    #region [站位上传中报错]

                        //    case PositionType.PositionSendError:
                        //        {
                        //            item.SubItems[3].Text = p.TestState;
                        //            item.SubItems[4].Text = p.PositionUpProcess;
                        //            break;
                        //        }

                        //    #endregion

                        //    #region [站位上传中]

                        //    case PositionType.FileUploadProcess:
                        //        {
                        //            item.SubItems[3].Text = @"文件上传中";
                        //            item.SubItems[4].Text = p.PositionUpProcess;
                        //            break;
                        //        }

                        //    #endregion

                        //    #region [站位上传结束]

                        //    case PositionType.FileUpload:
                        //        {
                        //            item.SubItems[3].Text = p.TestState;
                        //            item.SubItems[4].Text = @"0";
                        //            btnSendFile.Enabled = true;
                        //            timer1.Enabled = false;
                        //            break;
                        //        }

                        //        #endregion
                        //}


                        #endregion

                        ListViewItem item;
                        int index = this.listView_Position.Items.IndexOfKey(x.PositionIp);
                        if (index != -1)
                            item = this.listView_Position.Items[index];
                        else
                        {
                            //站位IP地址
                            item = listView_Position.Items.Add("");
                            //站位名称
                            item.SubItems.Add("");
                            //文件存放路径
                            item.SubItems.Add("");
                            //站位状态
                            item.SubItems.Add("");
                            //上传状态
                            //item.SubItems.Add("");
                            ////站位ID
                            //item.SubItems.Add("");
                            //Key
                            item.Name = x.PositionIp;
                        }

                        switch (y)
                        {
                            #region [站位上线]

                            case PositionType.PositionOnline:
                                {
                                    //本地文件夹路径
                                    x.PositionFolder =
                                        $@"{GlobalConstants.Disk}{x.PositionName}\{x.PartNo}";
                                    item.SubItems[0].Text = x.PositionIp;
                                    item.SubItems[1].Text = x.PositionName;
                                    item.SubItems[2].Text = x.PositionFolder;
                                    item.SubItems[3].Text = x.TestState;
                                    break;
                                }

                            #endregion

                            #region [站位下线]

                            case PositionType.PositionOffline:
                                {
                                    //.SubItems[3].Text = $@"{conn.PositionInfo.PositionName}下线";
                                    this.listView_Position.Items.RemoveByKey(x.PositionIp);
                                    this.RefListViewSysInfoMessage(
                                        $"IP地址：{x.PositionIp} 站位名：{x.PositionName}下线");
                                    break;
                                }


                            #endregion

                            #region [站位开始上传]

                            case PositionType.FileStart:
                                {

                                    item.SubItems[3].Text = x.TestState;
                                    // btnSendFile.Enabled = false;
                                    //timer1.Enabled = true;
                                    //timer1.Start();
                                    // Thread.Sleep(1000);
                                    //  MessageBox.Show("ok");
                                    // this.RefPositionDetail();
                                    break;
                                }

                            #endregion

                            #region [站位上传中报错]

                            case PositionType.PositionSendError:
                                {
                                    item.SubItems[3].Text = x.TestState;
                                    break;
                                }

                            #endregion

                            #region [站位上传中]

                            case PositionType.FileUploadProcess:
                                {
                                    item.SubItems[3].Text = @"文件上传中";
                                    break;
                                }

                            #endregion

                            #region [站位上传结束]

                            case PositionType.FileUpload:
                                {
                                    item.SubItems[3].Text = x.TestState;
                                    break;
                                }

                        #endregion

                        #region [更新机种名]
                            case PositionType.PositionUpdatePartNo:
                            {
                                item.SubItems[2].Text = x.PositionFolder;
                                break;
                            }
                            

                            #endregion
                    }
                }), position, positionType);
            }
            catch (Exception e)
            {
                LogHelper.Error(e);
            }
        }
        

        #endregion


        #region [刷新ListView_sysInfo控件]
        private void RefListViewSysInfoMessage(string msg)
        {
            if (_isStopping) return;
            try
            {
                this.listView_SysInfo.Invoke(new Action<string>(x =>
                {
                    ListViewItem item = this.listView_SysInfo.Items.Insert(0, StringUtils.GetDateStr(), "");
                    item.SubItems.Add(x);
                }), msg);
            }
            catch (Exception e)
            {
               LogHelper.Error(e);
            }
        }
        #endregion


        #region [获取当前选中的行]
        private ListViewItem GetSelectItem(ListViewEx listViewEx)
        {
            var items = listViewEx.SelectedItems;
            if (items.Count > 0)
                return items[0];
            return null;
        }
        #endregion


        #region [刷新ListView_Process控件]
        private void RefPositionDetail()
        {
            if (_isStopping) return;
            //获取当前选中行
            ListViewItem item = this.GetSelectItem(this.listView_Position);
            if (item == null) return;

            Position positions = socketServerHelper.PositionList.Find(p => p.PositionIp == item.Name);


            try
            {
                this.listView_Process.Invoke(new Action<Position>(x =>
                {
                    this.listView_Process.Items.Clear();
                    var positionDetails = x.PositionDetailsList.ToArray();
                    foreach (var detail in positionDetails)
                    {
                        ListViewItem items = this.listView_Process.Items.Insert(0, detail.DateTimeStr);
                        items.SubItems.Add(detail.FileName);
                        items.SubItems.Add("");
                    }
                   
                }), positions);
            }
            catch (Exception e)
            {
               LogHelper.Error(e);
            }
            
            
        }
        #endregion


        #region "发送文件"
        private void btnSendFile_Click(object sender, EventArgs e)
        {
            try
            {
                if (socketServerHelper == null || socketServerHelper.PositionList.Count == 0)
                {
                    MessageBox.Show(@"未获取到正确的机种,请先查询工单或者未发现上线客户端,请先上线");
                    return;
                }
                if (btnSendFile.Enabled)
                {
                    cancellation = new CancellationTokenSource();
                    cancellation.Token.Register(this.CallBackStopTask);
                    this.btnSendFile.Enabled = false;

                    if (socketServerHelper.IsConnected && socketServerHelper.PositionList.Count > 0)
                    {
                        task = Task.Run(() =>
                        {
                            foreach (var p in socketServerHelper.PositionList)
                            {
                                if (!this.GetLocalFolder(p.PositionFolder, p.PositionIp))
                                {
                                    RefreshForm(p, PositionType.PositionSendError);
                                }
                                else
                                {
                                    RefreshForm(p, PositionType.FileStart);
                                    socketServerHelper.SendFolder(p.PositionIp, p.PositionFolder);
                                }
                            }

                        });

                        task.ContinueWith((a) =>
                        {
                            foreach (var p in socketServerHelper.PositionList)
                            {
                                RefreshForm(p, PositionType.FileUpload);
                            }

                            this.btnSendFile.Invoke(new Action(() => { this.btnSendFile.Enabled = true; }));
                        });
                    }

                  
                }
                else
                {
                    TaskAbort();
                }


            }
            catch (AggregateException ae)
            {
                foreach (Exception exception in ae.InnerExceptions)
                {
                    if (exception is TaskCanceledException)
                       LogHelper.Error(((TaskCanceledException)exception).Message);
                    else
                        LogHelper.Info($"AggregateException{exception.GetType().Name}");
                }
            }
        }

        private void TaskAbort()
        {
            if (task != null)
            {
                cancellation?.Cancel();
            }
        }

        private void CallBackStopTask()
        {
            new Thread(delegate()
            {
                if (!this.IsDisposed)
                {
                    this.Invoke(new Action(() =>
                    {
                        this.btnSendFile.Enabled = true;
                        _isCancel = true;
                    }));
                }
            }).Start();
        }

        #endregion

        private void listView_Position_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
        {
            this.listView_Position.ProgressColumIndex = 4;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (this.listView_Position.Items.Count > 0)
            {
                this.listView_Position.Invoke(new MethodInvoker(() =>
                {
                    foreach (ListViewItem items in this.listView_Position.Items)
                    {
                        if (Convert.ToInt32(items.SubItems[4].Text) < 100)
                        {
                            items.SubItems[4].Text = (Convert.ToInt32(listView_Position.Items[0].SubItems[4].Text) + 1).ToString();
                        }
                    }
                }));
            }

        }

        private void BtnSelectFolder_Click(object sender, EventArgs e)
        {

        }

        #region [根据工号查找机种SQL]
        private string FindParNo(string workNo)
        {
            try
            {
                // return "Test";
                string sql = $"SELECT MSE0008.F002 FROM MSE0008 INNER JOIN MSE0017 ON MSE0008.F001 = MSE0017.F005 WHERE MSE0017.F003 = '{workNo}'";
                DataTable dt = OracleHelper.ExecToSqlGetTable(sql);
                if (dt != null && dt.Rows.Count > 0)
                {
                    return dt.Rows[0][0].ToString();
                }
                else
                {
                    return string.Empty;
                }
            }
            catch (Exception e)
            {
                LogHelper.Error(e);
                return string.Empty;
            }
        }
        #endregion

        #region [工单查询按钮事件]
        private void BtnSearch_Click(object sender, EventArgs e)
        {
            string workNo = TxtWorkNo.Text.Trim();

            if (workNo.Length > 0)
            {
                if (string.IsNullOrEmpty(FindParNo(workNo)))
                {
                    MessageBox.Show(@"未查询到此工单下机种信息");
                    TxtWorkNo.Focus();
                    TxtWorkNo.SelectAll();
                    return;
                }
                else
                {
                    if (_isFirst == false)
                    {
                        this.RefListViewSysInfoMessage(this.StartListen()
                            ? $"本机端口{GlobalConstants.LocalPort}监听成功"
                            : $"本机端口{GlobalConstants.LocalPort}监听失败");
                    }
                  
                    //if (!_isFirst) this.RefListViewSysInfoMessage(this.StartListen()
                    //    ? $"本机端口{GlobalConstants.LocalPort}监听成功"
                    //    : $"本机端口{GlobalConstants.LocalPort}监听失败");

                    LbPartNo.Text = FindParNo(workNo);
                    if (socketServerHelper.PositionList.Count > 0)
                    {
                        foreach (var p in socketServerHelper.PositionList)
                        {
                            p.PartNo = LbPartNo.Text.Trim();
                            p.PositionFolder = $@"{GlobalConstants.Disk}{p.PositionName}\{p.PartNo}";
                            RefreshForm(p, PositionType.PositionUpdatePartNo);
                        }
                        //this.listView_Position.Invoke(new MethodInvoker(() =>
                        //{
                        //    foreach (ListViewItem items in this.listView_Position.Items)
                        //    {
                        //        items.SubItems[2].Text = $@"{GlobalConstants.Disk}{socketServerHelper.ClientMsgModelInfo.PositionInfo.PositionName}\{socketServerHelper.ClientMsgModelInfo.PositionInfo.PartNo}";
                        //    }
                        //}));
                    }
                }
            }
            else
            {
                MessageBox.Show(@"请先输入工单号");
                return;
            }
        }
        #endregion

        #region [listView_Position选中单行明细事件]
        private void listView_Position_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            RefPositionDetail();
        }
        #endregion

    }

    #region[刷新界面信息枚举]
    public enum PositionType
    {
        /// <summary>
        /// 站位连接
        /// </summary>
        PositionSendError= 0,
        /// <summary>站位上线</summary>
        PositionOnline = 1,
        /// <summary>上传开始</summary>
        FileStart = 2,
        /// <summary>上传过程</summary>
        FileUploadProcess = 3,
        /// <summary>上传结束</summary>
        FileUpload = 4,
        /// <summary>
        /// 更新站位机种名
        /// </summary>
        PositionUpdatePartNo = 5,
        /// <summary>站位下线</summary>
        PositionOffline = -1
    }
    #endregion
}


